import { useUserStore } from '@/store';
import { errorHandler } from './errorHandler';
import request from '@/utils/request';

let refreshingPromise = null;

export async function handleTokenRefresh(originalRequest) {
  // 1. 防止因刷新后的重试请求再次失败（例如，新Token还是无效）而导致的无限循环
  if (originalRequest._retry) {
    console.error(
      'Request failed even after token refresh and retry.',
      originalRequest.url,
    );
    // 此时不应再尝试刷新，直接拒绝，并提示用户会话可能已失效
    await errorHandler.handleSessionExpired('会话已过期，请重新登录');
    return Promise.reject(new Error('Token refresh failed after retry.'));
  }
  originalRequest._retry = true;

  // 2. 使用“锁”机制，确保在同一时间内只有一个请求去触发Token刷新
  if (!refreshingPromise) {
    refreshingPromise = new Promise(async (resolve, reject) => {
      try {
        console.log('Token expired, attempting to refresh...');
        // 调用Pinia store中的业务方法
        const { refreshToken } = useUserStore();
        const newAccessToken = await refreshToken();
        console.log('Token refreshed successfully.');
        resolve(newAccessToken);
      } catch (error) {
        console.error('Failed to refresh token:', error);
        // 刷新失败，通常意味着refresh_token也失效了，需要强制用户登出
        await errorHandler.handleSessionExpired('您的会话已过期，请重新登录');
        reject(error);
      } finally {
        // 3. 无论成功或失败，完成后都必须清空锁，以便下次Token过期时可以重新触发刷新
        refreshingPromise = null;
      }
    });
  }

  try {
    // 4. 等待刷新操作完成（无论是当前请求触发的还是其他请求触发的）
    const newAccessToken = await refreshingPromise;

    // 5. 更新当前失败请求的请求头
    originalRequest.headers.Authorization = `Bearer ${newAccessToken}`;
    console.log(`Retrying request: ${originalRequest.url}`);

    // 6. 使用 request 实例重新发起原始请求
    return request(originalRequest);
  } catch (error) {
    // 7. 如果 refreshingPromise 本身失败了，则直接拒绝当前请求
    return Promise.reject(error);
  }
}
